package com.youxin.admin.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.youxin.admin.annotation.RequirePermissions;
import com.youxin.base.BaseResultCode;
import com.youxin.base.TResult;
import com.youxin.common.constant.RedisKey;
import com.youxin.context.BaseContextHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Optional;
import java.util.StringTokenizer;

/**
 * description: PermissionHandlerInterceptor <br>
 * date: 2020/3/2 16:13 <br>
 * author: llkj <br>
 * version: 1.0 <br>
 */
@Component
public class PermissionHandlerInterceptor extends HandlerInterceptorAdapter {

    private static final Logger logger = LoggerFactory.getLogger(PermissionHandlerInterceptor.class);

    @Resource
    @Lazy
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        RequirePermissions annotation = handlerMethod.getBeanType().getAnnotation(RequirePermissions.class);
        if (annotation == null) {
            annotation = handlerMethod.getMethodAnnotation(RequirePermissions.class);
        }
        if(annotation == null){
            return super.preHandle(request, response, handler);
        }
        String permission = annotation.value();
        String token = BaseContextHandler.getToken();
        if(StringUtils.isEmpty(token)){
             returnJson(response);
             return false;
        }
        String userInfo = stringRedisTemplate.opsForValue().get(RedisKey.ADMIN_USER_INFO+ token);
        String permissions = Optional.ofNullable(userInfo).map(JSONObject::parseObject).map(item->item.getString("permissions")).orElse("");
        if(StringUtils.isEmpty(permissions)){
            returnJson(response);
            return false;
        }
        boolean flag = Arrays.stream(StringUtils.tokenizeToStringArray(permissions,",")).filter(item -> permission.equals(item)).findAny().isPresent();
        if(!flag){
            returnJson(response);
            return false;
        }
        return super.preHandle(request, response, handler);
    }

    private void returnJson(HttpServletResponse response){
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");

        try {
            writer = response.getWriter();
            TResult result =TResult.build(BaseResultCode.COMMON_FAIL,"您无权限访问此操作");
            writer.print(JSONObject.toJSONString(result));
        } catch (IOException e){
            logger.error("拉截器异常",e);
        } finally {
            if(writer != null){
                writer.close();
            }
        }
    }
}
